package reflex

import (
	"fmt"
	"reflect"

	"gitee.com/shijingzhao/go-frame/utils"
)

func Deref(t reflect.Type) reflect.Type {
	if t.Kind() == reflect.Ptr {
		return t.Elem()
	} else {
		return t
	}
}

// ValuesPtr 返回结构遍历给定的字段的值
func ValuesPtr(v reflect.Value, values []interface{}) {
	for i := range values {
		values[i] = reflect.Indirect(v).Field(i).Addr().Interface()
	}
}

func MapToStruct(input map[string]interface{}, output interface{}) error {
	// 校验是否是结构类型
	valueOfDest := reflect.ValueOf(output).Elem()
	if valueOfDest.Kind() != reflect.Struct {
		return fmt.Errorf("应为%s,但得到%s", reflect.Struct, valueOfDest.Kind())
	}

	// 获取结构体实例的反射类型对象
	typeOfDest := reflect.TypeOf(output).Elem()

	// 遍历结构体所有成员
	for i := 0; i < typeOfDest.NumField(); i++ {
		// 获取每个成员的结构体字段类型
		fieldType := typeOfDest.Field(i)

		mapValue, _ := input[fieldType.Tag.Get("json")]

		switch fieldType.Type.Kind() {
		case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
			valueOfDest.FieldByName(fieldType.Name).SetInt(utils.ToInt64(mapValue))

		case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64:
			valueOfDest.FieldByName(fieldType.Name).SetInt(utils.ToInt64(mapValue))

		case reflect.String:
			valueOfDest.FieldByName(fieldType.Name).SetString(mapValue.(string))

		case reflect.Bool:
			valueOfDest.FieldByName(fieldType.Name).SetBool(utils.ToBool(mapValue))
		}
	}

	return nil
}
